﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Ninject;
using Legazpi.Payroll.BusinessLogic.Services;
using Legazpi.Payroll.BusinessLogic.Services.Interfaces;
using Legazpi.Payroll.DataAccess.DataObjects;
using Web.Codes;
using Web.Utils;
using Legazpi.Payroll.Web.Models;
using Newtonsoft.Json;

namespace Legazpi.Payroll.Web.Admin.Payroll
{
    public partial class DailyTimeEntry : System.Web.UI.Page
    {
        [Inject]
        public IDayTimeRecordService _dayTimeRecordService { get; set; }
        [Inject]
        public IEmployeeService _employeeService { get; set; }
        [Inject]
        public IPayrollDateService _payrollDateService { get; set; }

        public bool IsSuccess { get; set; }
        public bool IsError { get; set; }   
        
        public string NotifyText { get; set; }

        protected double RunningBalance { get; private set; }

        private int _currentEmployeeId;
        public int CurrentEmployeeId
        {
            get
            {
                int id;
                return int.TryParse(EmployeeIdHidden.Value, out id) ? id : 0;
            }
            set
            {
                _currentEmployeeId = value;
                EmployeeIdHidden.Value = _currentEmployeeId.ToString();
            }
        }
        private int _currentPaydateId;
        public int CurrentPaydateId
        {
            get
            {
                int id;
                return int.TryParse(PayrollPeriodDdl.SelectedValue.ToString(), out id) ? id : 0;
            }
            set
            {
                _currentPaydateId = value;
                var item = PayrollPeriodDdl.Items.FindByValue(_currentPaydateId.ToString());
                if (item != null)
                {
                    PayrollPeriodDdl.ClearSelection();
                    item.Selected = true;
                }
            }
        }
        private int _currentDTREntryId;
        public int CurrentDTREntryId
        {
            get
            {
                int id;
                return int.TryParse(DTRIdHidden.Value, out id) ? id : 0;
            }
            set
            {
                _currentDTREntryId = value;
                DTRIdHidden.Value = _currentDTREntryId.ToString();
            }
        }
        private List<TimeRecord> _timeRecordList;
        public List<TimeRecord> TimeRecordList
        {
            get
            {
                _timeRecordList = new List<TimeRecord>();
                foreach (RepeaterItem item in repeaterRecordEntry.Items)
                {
                    var dayLiteral = (Literal)item.FindControl("DayLiteral");
                    var timeInTextBox = (TextBox)item.FindControl("INtextItem");
                    var timeOutTextBox = (TextBox)item.FindControl("OuttextItem");
                    var holidayDropDown = (DropDownList)item.FindControl("HolidayDropdown");

                    DateTime tempDate;
                    var timeRecord = new TimeRecord();
                    timeRecord.Day = int.Parse(dayLiteral.Text);
                    if (DateTime.TryParse(timeInTextBox.Text, out tempDate))
                        timeRecord.TimeIn = tempDate;
                    if (DateTime.TryParse(timeOutTextBox.Text, out tempDate))
                        timeRecord.TimeOut = tempDate;
                    timeRecord.Holiday = int.Parse(holidayDropDown.SelectedValue);
                    _timeRecordList.Add(timeRecord); 
                }
                return _timeRecordList;                
            }
            set
            {
                _timeRecordList = value;                
            }
        }
        public double CurrentEmployeeCashAdvanceBalance { get; set; }

        #region Implementations for data entry
        void ResetFigures()
        {
            RunningBalance = 0;
            //CurrentEmployeeCashAdvanceBalance = _employeeAdjustmentService.GetEmployeeCashAdvanceBalance(CurrentEmployeeId);
        }
        void BindGridDTR(List<TimeRecord> source = null)
        {
            var sourceList = GetDefaultList(source);

            repeaterRecordEntry.DataSource = sourceList;
            repeaterRecordEntry.DataBind();
        }
        List<TimeRecord> GetDefaultList(List<TimeRecord> source)
        {
            List<TimeRecord> list = new List<TimeRecord>();
            var currentPayrollDate = _payrollDateService.GetById(CurrentPaydateId);
            int startDay = currentPayrollDate.Startdate.Day;
            int endDay = currentPayrollDate.Enddate.Day;   
            for (int iDay = startDay; iDay <= endDay; iDay++)
            {
                TimeRecord timeRecord = null;
                if(source != null)
                    timeRecord = source.Find(x=> x.Day == iDay);

                if (timeRecord == null)
                    timeRecord = new TimeRecord { Day = iDay };

                list.Add(timeRecord);
            }
            return list;
        }
        void Delete(int id)
        {
            //_employeeAdjustmentService.Delete(id);
            //IsSuccess = _employeeAdjustmentService.Save();
            //NotifyText = "Successfully Deleted.";
            //BindGrid();
        }

        void Edit(int empId)
        {
            if (PayrollPeriodDdl.SelectedIndex <= 0)
            {
                IsError = true;
                NotifyText = "Must Select Payperiod";
                return;
            }
            var emp = _employeeService.GetById(empId);

            if (emp == null)
                return;

            ObjectToData(emp);

            CurrentEmployeeId = emp.Id;
            
            SubmitBtn.Text = "Update";
        }

        void Update(int id)
        {
            var dtr = _dayTimeRecordService.GetById(id);
            if (dtr == null)
            {
                Add();
                return;
            }
            DataToObject(ref dtr);

            _dayTimeRecordService.Update(dtr);
            CurrentDTREntryId = dtr.Id;

            IsSuccess = _dayTimeRecordService.Save();
            NotifyText = "Successfully Updated Record.";
        }
        void Add()
        {
            var dtr = new DayTimeRecord();

            DataToObject(ref dtr);

            _dayTimeRecordService.Add(dtr);
            IsSuccess = _dayTimeRecordService.Save();

            CurrentDTREntryId = dtr.Id; 
            NotifyText = "Successfully Added New DTR Record.";
            SubmitBtn.Text = "Update";
        }
        void ClearForm()
        {
            //ClearControl(this.Page);
            //CurrentEmployeeAdvId = 0;
            //SubmitBtn.Text = "Submit";
        }
        void ClearControl(Control ctrl)
        {
            foreach (Control _ctrl in ctrl.Controls)
            {
                if (_ctrl.GetType() == typeof(TextBox))
                {
                    ((TextBox)_ctrl).Text = string.Empty;
                }
                else if (_ctrl.GetType() == typeof(DropDownList))
                {
                    ((DropDownList)_ctrl).SelectedIndex = 0;
                }
                ClearControl(_ctrl);
            }
        }
        void Save()
        {
            if (CurrentDTREntryId == 0)
                Add();
            else
                Update(CurrentDTREntryId);
        }
        void DataToObject(ref DayTimeRecord obj)
        {             
            obj.EmployeeId = CurrentEmployeeId;            
            obj.PayrollDateId = CurrentPaydateId;
            obj.LogTimeRecords = JsonConvert.SerializeObject(TimeRecordList);
        }

        void ObjectToData(Employee obj)
        {
            var dtr = _dayTimeRecordService.GetEmployeeDTRbyPayroll(obj.Id , CurrentPaydateId);           
            EmployeeName.Text = string.Format("{0} {1} ({2}) - {3}", obj.FirstName, obj.LastName, obj.EmployeeCode, obj.Position.Code);
            if (dtr != null)
            {
                var employeeDTR = EmployeeDTR.GetDTO(dtr);
                CurrentDTREntryId = dtr.Id;
                BindGridDTR(employeeDTR.TimeRecords);
            }
            else
            {
                BindGridDTR(null);
            }
                           
        }

        #endregion
        #region Implementations for employee listing
        void BindGridEmployeeList()
        {
            int tempInt;
            var sectorId = int.TryParse(SectorFilterDropList.SelectedValue, out tempInt) ? tempInt : 0;
            repeater.DataSource = _employeeService.GetAll().Where(x => x.Detachment.SectorId == sectorId).ToList();
            repeater.DataBind();
        }

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                var activePayrollDate = _payrollDateService.GetActivePayroll();

                PayrollPeriodDdl.ToPayrollPeriodSelectList(activePayrollDate != null ? activePayrollDate.Id : 0);

                SectorFilterDropList.ToSectorSelectList(0);
                BindGridEmployeeList();
            }

        }

        protected void repeater_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            int intTemp = 0;
            if (int.TryParse((string)e.CommandArgument, out intTemp))
            {
                switch (e.CommandName.ToLower())
                {
                    case Constants.Update_Command:
                        Edit(intTemp);
                        break;
                }
            }
        }
        protected void repeater_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                var codeLiteral = e.Item.FindControl("CodeLiteral") as Literal;
                var nameLiteral = e.Item.FindControl("NameLiteral") as Literal;
                var positionLiteral = e.Item.FindControl("PositionLiteral") as Literal;
                var workHoursLiteral = e.Item.FindControl("WorkHoursLiteral") as Literal;                

                var employeeItem = ((Employee)e.Item.DataItem);
                codeLiteral.Text = employeeItem.EmployeeCode;
                nameLiteral.Text = employeeItem.FirstName;
                positionLiteral.Text = employeeItem.Position.Code;
            }
        }
        protected void repeaterRecordEntry_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                var dayLiteral = e.Item.FindControl("DayLiteral") as Literal;
                var inTextItem = e.Item.FindControl("INtextItem") as TextBox;
                var outTextItem = e.Item.FindControl("OuttextItem") as TextBox;
                var workHoursLiteral = e.Item.FindControl("WorkHoursLiteral") as Literal;
                var holidayDropdown = e.Item.FindControl("HolidayDropdown") as DropDownList;

                var timeRecordItem = ((TimeRecord)e.Item.DataItem);
                dayLiteral.Text = timeRecordItem.Day.ToString();                
                inTextItem.Text = timeRecordItem.TimeIn.HasValue ? timeRecordItem.TimeIn.Value.ToString("HH:mm") : string.Empty;
                outTextItem.Text = timeRecordItem.TimeOut.HasValue ? timeRecordItem.TimeOut.Value.ToString("HH:mm") : string.Empty;
                workHoursLiteral.Text = timeRecordItem.TotalWorkHours.ToString();

                var item = holidayDropdown.Items.FindByValue(timeRecordItem.Holiday.ToString());
                if (item != null)
                {
                    holidayDropdown.ClearSelection();
                    item.Selected = true;
                }
            }
        }
        protected void SubmitBtn_Click(object sender, EventArgs e)
        {
            Save();
            if (IsSuccess)
            {
                ClearForm();
                BindGridEmployeeList();
            }
        }

        protected void CancelBtn_Click(object sender, EventArgs e)
        {
            ClearForm();
        }
        protected void SearchBtn_Click(object sender, EventArgs e)
        {
            if (CurrentEmployeeId > 0)
                Edit(CurrentEmployeeId);
        }
        protected void PayrollPeriodDdl_SelectedIndexChanged(object sender, EventArgs e)
        {
            ClearForm();
            BindGridEmployeeList();
        }

        protected void SectorFilterDropList_SelectedIndexChanged(object sender, EventArgs e)
        {
            BindGridEmployeeList();
        }
    }
}